/*
 * 测试封装 
 */

/*
// 定义变量
let username ; // 仅声明变量并未显式赋值
console.log( username ); // undefined

// 初始化username变量 (定义变量之后首次赋值就是初始化)
username = 'kaifamiao' ;
console.log( username ); // kaifamiao
*/

// 定义对象
function Decimal(value){

    // 通过 this.propertyName 形式定义的变量属于实例属性
    // 比如 this.value 就是定义了一个名称为 value 的实例属性
    this.value = value ; // 通过构造函数的参数值来初始化该属性

    // 定义局部变量，将 value 保存起来
    const VALUE = this.value ;// 获取value属性的值并将其赋值给一个常量

    // 定义局部变量 (作为私有变量来使用)
    const SYMBOLS = ['0','1','2','3','4','5','6','7','8','9',
                     'A','B','C','D','E','F','G','H','I','J',
                     'K','L','M','N','O','P','Q','R','S','T',
                     'U','V','W','X','Y','Z'];

    // 在构造函数内声明的内部函数(没有通过this绑定到当前实例)属于私有函数 
    function to(radix){ // 参数所传入的表示基数
        let str = '' ; // 用来记录整数所对应的进制形式的变量
        let n = VALUE ; // 将外部函数中VALUE常量的值赋值给变量 n
        console.log( 'n: ' , n );
        while( n > 0 ){
            let index = n % radix ;
            str = SYMBOLS[ index ] + str ;
            n = ( n / radix ) | 0 ; // 让n除以radix求商取整，并重新赋值给n变量
        }
        return str ;
    }

    // 通过 this.functionName 形式声明的函数属于实例方法
    // 比如 this.toBinary 就是定义了一个名称为 toBinary 的实例方法
    this.toBinary = function(){
        let bin = to(2); // 调用私有函数将整数转换为二进制形式
        return bin ; // 返回二进制形式
    }

    this.toOctal = function(){
        return to(8) ;
    }

    this.toHex = function(){
        return to(16) ;
    }
}

// 变量 x 指向了堆内存中 Decimal对象的一个实例
let x = new Decimal(81);

let bin = x.toBinary(); // 调用x指向的实例的toBinary方法求x指向的实例内部的整数的二进制形式
console.log( bin );

let oct = x.toOctal(); // 调用x指向的实例的toOctal方法求x指向的实例内部的整数的八进制形式
console.log( oct );

let hex = x.toHex();
console.log( hex );